# print("Starting app.py")
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()

from flask import Flask, jsonify, request
from flask_cors import CORS
from flasgger import Swagger
from pymongo import MongoClient
import os
from datetime import datetime
import uuid
# 根据环境选择配置文件
import os
if os.environ.get('DOCKER_ENV') == 'true':
    from config_docker import Config
else:
    from config import Config
from middleware.api_gateway import APIGateway
from middleware.unified_abstraction import UnifiedAbstractionLayer
from services.scm import SmartContractManager
from services.scvm import SmartContractVersionManager
from services.bmn import BlockchainMonitoringNetwork
from services.rag import RegulatoryAuditGateway
from services.mag import MultiChainAdaptationGateway
from adapters.adapter_factory import AdapterFactory
from utils.logger import setup_application_logging
from utils.auth import AuthManager

# print("Imports successful in app.py")

def create_app(config_class=Config):
    print("Inside create_app() - Start")
    app = Flask(__name__)
    print("Inside create_app() - Flask app initialized")
    app.config.from_object(config_class)
    print("Inside create_app() - Config loaded")
    
    # 启用CORS
    CORS(app)
    print("Inside create_app() - CORS enabled")
    
    # 配置Swagger
    swagger_config = {
        "headers": [],
        "specs": [
            {
                "endpoint": "apispec",
                "route": "/apispec.json",
                "rule_filter": lambda rule: True,  # 所有端点
                "model_filter": lambda tag: True,  # 所有模型
            }
        ],
        "static_url_path": "/flasgger_static",
        "swagger_ui": True,
        "specs_route": "/swagger/"
    }
    print("Inside create_app() - Swagger config defined")
    
    swagger_template = {
        "swagger": "2.0",
        "info": {
            "title": "区块链中间件API",
            "description": "提供统一的区块链访问接口，支持多种主流区块链平台",
            "version": "2.0.0",
            "contact": {
                "name": "区块链中间件团队",
                "email": "blockchain@example.com"
            },
        },
        "securityDefinitions": {
            "ApiKeyAuth": {
                "type": "apiKey",
                "name": "X-API-Key",
                "in": "header"
            }
        },
        "security": [
            {"ApiKeyAuth": []}
        ],
        "tags": [
            {"name": "Chain", "description": "区块链连接和信息相关接口"},
            {"name": "Block", "description": "区块查询相关接口"},
            {"name": "Transaction", "description": "交易相关接口"},
            {"name": "Contract", "description": "智能合约相关接口"},
            {"name": "Admin", "description": "管理功能相关接口"}
        ]
    }
    print("Inside create_app() - Swagger template defined")
    
    Swagger(app, config=swagger_config, template=swagger_template)
    print("Inside create_app() - Swagger initialized")
    
    # 初始化MongoDB连接
    try:
        print("Inside create_app() - Attempting MongoDB connection")
        print(f"MongoDB URI: {app.config['MONGODB_URI']}")
        print(f"Database Name: {app.config['DATABASE_NAME']}")
        
        mongo_client = MongoClient(app.config['MONGODB_URI'])
        app.mongo_db = mongo_client[app.config['DATABASE_NAME']]
        
        # 测试连接和认证
        app.mongo_db.command('ping')
        print("Inside create_app() - MongoDB connected and authenticated successfully")
        
    except Exception as e:
        print(f"Inside create_app() - MongoDB connection failed: {e}")
        raise
    
    # 初始化日志
    try:
        print("Inside create_app() - Setting up application logging")
        logger = setup_application_logging()
        app.logger = logger
        print("Inside create_app() - Application logging setup complete")
    except Exception as e:
        print(f"Inside create_app() - Logging setup failed: {e}")
        # Continue without custom logger if setup fails, Flask default might still work
        pass # Or raise, depending on how critical logging is at this stage
    
    # 初始化认证管理器
    print("Inside create_app() - Initializing AuthManager")
    auth_manager = AuthManager(app.config['SECRET_KEY'], app.config.get('ADMIN_API_KEY'))
    print("Inside create_app() - AuthManager initialized")
    
    # 初始化适配器工厂
    print("Inside create_app() - Initializing AdapterFactory")
    adapter_factory = AdapterFactory()
    print("Inside create_app() - AdapterFactory initialized")
    
    # 初始化统一抽象层
    print("Inside create_app() - Initializing UnifiedAbstractionLayer")
    unified_layer = UnifiedAbstractionLayer(config_class)
    print("Inside create_app() - UnifiedAbstractionLayer initialized")
    
    # 初始化中间件服务
    print("Inside create_app() - Initializing SCM")
    scm = SmartContractManager(app.mongo_db)
    print("Inside create_app() - SCM initialized")
    print("Inside create_app() - Initializing SCVM")
    scvm = SmartContractVersionManager(app.mongo_db)
    print("Inside create_app() - SCVM initialized")
    print("Inside create_app() - Initializing BMN")
    bmn = BlockchainMonitoringNetwork(app.mongo_db)
    print("Inside create_app() - BMN initialized")
    print("Inside create_app() - Initializing RAG")
    rag = RegulatoryAuditGateway(app.mongo_db)
    print("Inside create_app() - RAG initialized")
    print("Inside create_app() - Initializing MAG")
    mag = MultiChainAdaptationGateway(app.mongo_db)
    print("Inside create_app() - MAG initialized")
    
    # 将服务实例添加到app上下文（在初始化API网关之前）
    app.auth_manager = auth_manager
    
    # 初始化API网关
    api_gateway = APIGateway(app)
    
    # 注册蓝图
    from routes.chain_routes import chain_bp
    from routes.block_routes import block_bp
    from routes.transaction_routes import transaction_bp
    from routes.contract_routes import contract_bp
    from routes.admin_routes import admin_bp
    
    app.register_blueprint(chain_bp, url_prefix='/api/v1')
    app.register_blueprint(block_bp, url_prefix='/api/v1')
    app.register_blueprint(transaction_bp, url_prefix='/api/v1')
    app.register_blueprint(contract_bp, url_prefix='/api/v1')
    app.register_blueprint(admin_bp, url_prefix='/api/v1/admin')
    
    # 将服务实例添加到app上下文
    app.api_gateway = api_gateway
    app.unified_layer = unified_layer
    app.scm = scm
    app.scvm = scvm
    app.bmn = bmn
    app.rag = rag
    app.mag = mag
    
    # 健康检查端点
    @app.route('/api/v1/health')
    def health_check():
        return jsonify({
            'status': 'healthy',
            'timestamp': datetime.utcnow().isoformat(),
            'version': '2.0.0'
        })
    
    # 全局错误处理
    @app.errorhandler(400)
    def bad_request(error):
        return jsonify({
            'success': False,
            'error': {
                'code': 'INVALID_INPUT',
                'message': 'Invalid request parameters'
            },
            'data': None,
            'requestId': str(uuid.uuid4())
        }), 400
    
    @app.errorhandler(401)
    def unauthorized(error):
        return jsonify({
            'success': False,
            'error': {
                'code': 'UNAUTHENTICATED',
                'message': 'Authentication required'
            },
            'data': None,
            'requestId': str(uuid.uuid4())
        }), 401
    
    @app.errorhandler(403)
    def forbidden(error):
        return jsonify({
            'success': False,
            'error': {
                'code': 'UNAUTHORIZED',
                'message': 'Insufficient permissions'
            },
            'data': None,
            'requestId': str(uuid.uuid4())
        }), 403
    
    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            'success': False,
            'error': {
                'code': 'NOT_FOUND',
                'message': 'Resource not found'
            },
            'data': None,
            'requestId': str(uuid.uuid4())
        }), 404
    
    @app.errorhandler(500)
    def internal_error(error):
        return jsonify({
            'success': False,
            'error': {
                'code': 'INTERNAL_ERROR',
                'message': 'Internal server error'
            },
            'data': None,
            'requestId': str(uuid.uuid4())
        }), 500
    
    return app

if __name__ == '__main__':
    print("In __main__ block - Start")
    try:
        app = create_app()
        print("In __main__ block - create_app() successful")
        print("In __main__ block - Attempting to run app")
        app.run(host='0.0.0.0', port=5000, debug=True) # Added debug=True
        print("In __main__ block - app.run() finished (should not happen for dev server)")
    except Exception as e:
        print(f"In __main__ block - An error occurred: {e}")
        import traceback
        traceback.print_exc()
    print("In __main__ block - End")